package com.pocket.insight.base.mql.relation;

import com.pocket.insight.base.mql.Relation;
import com.pocket.insight.base.mql.TypedVal;
import com.pocket.insight.base.sql.Dialect;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 描述：
 *
 * @author shuize
 * @create 2024/12/10
 */
public class UnionRelation extends BaseRelation {

    public List<Relation> subRelations;

    public UnionRelation(Dialect dialect) {
        this.subRelations = new ArrayList<>();
        this.dialect = dialect;
    }

    @Override
    public TypedVal toQuery() {
        if (fetchRunTime().query != null) {
            return fetchRunTime().query;
        }
        this.subRelations.forEach(sub -> {
            if (sub.getIsSourceVirtualDialect(getDialect()).booleanValue()) {
                sub.setDialect(getDialect());
            }
        });
        Long offset = null;
        Long limit = null;
        if (this.subRelations.size() > 1) {
            Relation lastRelation = this.subRelations.get(this.subRelations.size() - 1);
            if (lastRelation instanceof StatementRelation) {
                StatementRelation statement = (StatementRelation) lastRelation;
                statement.isUnionSubRelation = true;
            }
        }
        TypedVal query = getConversion().unionQueryPack(this.subRelations.stream().map(r -> r.getQueryForReused(r.toQuery(), null, Boolean.valueOf((r != null && (r.fetchRunTime()).accessCount.equals((fetchRunTime()).accessCount))))).collect(Collectors.toList()));
        if (StringUtils.isBlank(getAlias())) {
            (fetchRunTime()).query = query;
            return query;
        }
        if (offset != null || limit != null) {
            if (offset == null) {
                offset = Long.valueOf(0L);
            }
            query = this.dialect.setPage(query, offset, limit);
        }
        (fetchRunTime()).query = getConversion().bracketQueryWithAlias(query, getAlias());
        return (fetchRunTime()).query;
    }

    public UnionRelation add(Relation relation) {
        this.subRelations.add(relation);
        return this;
    }
}
